# ListIndicator - Displays currently selected item and length of the list
# Copyright (C) 2007 Lauri Taimila
# 
# Entertainer is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# Entertainer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import pango
import clutter
from frontend.gui.widgets.arrow_texture import ArrowTexture

class ListIndicator(clutter.Group):
    """
    ListIndicator displays 'current / maximum' value label and arrows.
    """
    
    # Direction
    # HORIZONTAL layout: ARROW_LEFT current / maximum ARROW_RIGHT
    # VERITCAL layout:   current / maximum ARROW_UP ARROW_DOWN
    HORIZONTAL = 0
    VERTICAL = 1
    
    def __init__(self, width, height, theme, direction):
        """
        Initialize actor.
        @param width: Width of the widget in percentage (0-1)
        @param height: Height of the widget in percentage (0-1)
        @param theme: Theme object
        @param direction: Direction (constant of this class)
        """
        clutter.Group.__init__(self)
        
        # Size
        stage = clutter.Stage()
        self.stage_w = stage.get_width()
        self.stage_h = stage.get_height()
        self.width_factor = width
        self.height_factor = height
        self.w = int(self.stage_w * self.width_factor)
        self.h = int(self.stage_h * self.height_factor)
        
        self.direction = direction
        self.delimiter = " / "
        self.current = 1
        self.maximum = 1
        
        self.theme = theme
        self.fg = theme.getColor("arrow_foreground")
        self.bg = theme.getColor("arrow_background")
        
        # Use transparent rectangle to set size of the scroll area
        # FIXME: Is there another way? This seems a bit hackish solution.
        rect = clutter.Rectangle()
        rect.set_size(int(self.stage_w * self.width_factor), int(self.stage_h * self.height_factor))
        rect.set_color(clutter.Color(255,255,255,0))
        rect.show()
        self.add(rect)
        
        # Create and initialize text label
        self.text = clutter.Label()
        self.text.set_color(theme.getColor("text"))
        self.text.set_font_name(self.theme.getFont() + " " + str(self.h * 0.8) + "px")
        self.text.set_text(str(self.maximum) + self.delimiter + str(self.maximum))
        self.text.set_line_wrap(False)
        
        # Set text into the middle if horizontal. Next to arrows if vertical
        if direction == ListIndicator.VERTICAL:
            self.text.set_position(0, int(self.stage_h * self.height_factor / 2))
        else:
            self.text.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER)
            self.text.set_position(int(self.stage_w * self.width_factor / 2), int(self.stage_h * self.height_factor / 2))
            
        self.text.show()
        self.add(self.text)
        
        # Create arrows and calculate positions on screen
        if direction == ListIndicator.VERTICAL:
            self.arrow1 = ArrowTexture(int(self.stage_h * self.height_factor), self.fg, self.bg, ArrowTexture.UP)
            self.arrow2 = ArrowTexture(int(self.stage_h * self.height_factor), self.fg, self.bg, ArrowTexture.DOWN)
            self.arrow1.set_position(int(self.w - self.h / 2.0), int(self.h / 2.0))
            self.arrow2.set_position(int(self.w - (self.h * 1.5 + self.h / 6.0)), int(self.h / 2.0))
            
        elif direction == ListIndicator.HORIZONTAL:
            self.arrow1 = ArrowTexture(int(self.stage_h * self.height_factor), self.fg, self.bg, ArrowTexture.LEFT)
            self.arrow2 = ArrowTexture(int(self.stage_h * self.height_factor), self.fg, self.bg, ArrowTexture.RIGHT)
            self.arrow1.set_position(int(self.h / 2.0), int(self.h / 2.0))
            self.arrow2.set_position(int(self.w - self.h / 2.0), int(self.h / 2.0))
            
        self.arrow1.show()
        self.arrow2.show()
        self.add(self.arrow1)
        self.add(self.arrow2)
        
    def set_current(self, value):
        """
        Set current value
        @param number: Current value (between 1 - maximum)
        """
        if value > 0 and value <= self.maximum:
            self.current = value
            self._update_widget_actors()
            
            # Bounce arrow if user has reached the limit
            if self.current == 1:
                self.arrow1.bounce()
            elif self.current == self.maximum:
                self.arrow2.bounce()
    
    def get_current(self):
        """
        Get current value
        @return Current value (integer)
        """
        return self.current
        
    def set_maximum(self, value):
        """
        Set maximum value of the indicator
        @param number: Set maximum value
        """
        self.maximum = value
        self._update_widget_actors()
    
    def get_maximum(self):
        """
        Get maximum value.
        @return Max value (integer)
        """
        return self.maximum
            
    def set_delimiter(self, delimiter):
        """
        Set delimiter text that is displayed between current and maximum value.
        Default delimiter text is ' / ' spaces included.
        @param delimiter: delimiter text
        """
        self.delimiter = delimiter
        self._update_widget_actors()  
    
    def show_position(self):
        """
        Show position text that indicates the current position of the content.
        """
        self.text.show()
        
    def hide_position(self):
        """
        Hide position text that indicates the current position of the content.
        If this is called then indicator shows only arrows.
        """
        self.text.hide()
    
    def _update_widget_actors(self):
        """
        Update widget actors.
        """
        
        # Update text
        self.text.set_text(str(self.current) + self.delimiter + str(self.maximum))
        if self.direction == ListIndicator.VERTICAL:
            self.text.set_width(int(self.w - (self.h * 2.7)))
            self.text.set_alignment(pango.ALIGN_RIGHT)
            self.text.set_anchor_point(self.text.get_width(), int(self.text.get_height() / 2.0))
            self.text.set_position(self.text.get_width(), int(self.h / 2))
        else:
            self.text.set_width(int(self.w - (self.h * 2.7)))
            self.text.set_alignment(pango.ALIGN_CENTER)
            self.text.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER)
            self.text.set_position(int(self.w / 2), int(self.h / 2))
            